#ifndef _RBM_H_
#define _RBM_H_






class RBM {  
    
    public:  
    int N;  
    int n_visible;  
    int n_hidden;  
    double **W;  
    double *hbias;  
    double *vbias;  

    RBM(int, int, int, double**, double*, double*);  
    ~RBM(); 
    
    
    void contrastive_divergence(int*, double, int);  
    void sample_h_given_v(int*, double*, int*);  
    void sample_v_given_h(int*, double*, int*);  
    double propup(int*, double*, double);  
    double propdown(int*, int, double);  
    void gibbs_hvh(int*, double*, int*, double*, int*);  
    void reconstruct(int*, double*);  
};  


class HiddenLayer {
    

    int N;

public:
    HiddenLayer(int size, int in, int out, double **w, double *bp);
    ~HiddenLayer();

    double** W;
    double* b;

    int n_in;
    int n_out;


    double output(int *input, double *w, double b);
    void sample_h_given_v(int *input, int *sample);

};

//逻辑归类
class LogisticRegression {
    
    

    

    int N;

public:
    LogisticRegression(int size, int in, int out);
    ~LogisticRegression();

    double** W;
    double* b;

    int n_in;
    int n_out;



    void train(int *x, int *y, double lr);
    void softmax(double *x);
    void predict(int *x, double *y);            //预测

};


class DBN {
    LogisticRegression* log_layer;

    HiddenLayer**    sigmoid_layers;
    RBM**           rbm_layers;
    int N;

    int n_layers;
    int n_outs;
    int n_ins;


    int* hidden_layer_sizes;

public:
    DBN(int size, int n_i, int *hls, int n_o, int n_l);
    ~DBN();

    void pretrain(int *input, double lr, int k, int epochs);
    //微调
    void finetune(int *input, int *label, double lr, int epochs);
    //预测 
    void predict(int *x, double *y);


};



#endif


